part of '../widgets.dart';

enum VanCellSize { normal, large }

enum VanCellLayout { horizontal, vertical }

enum VanCellArrowDirection {
  right(Icons.keyboard_arrow_right),
  left(Icons.keyboard_arrow_left),
  up(Icons.keyboard_arrow_up),
  down(Icons.keyboard_arrow_down);

  final IconData iconData;

  const VanCellArrowDirection(this.iconData);
}

class VanCell extends StatelessWidget {
  /// props - 单元格大小，可选值为 large (默认: normal)
  final VanCellSize size;

  /// props - 布局方式，可选值为 vertical (默认:horizontal)
  final VanCellLayout? layout;

  /// props - 是否显示内边框(默认: true)
  final bool? border;

  /// props - 点击后跳转的链接地址
  final String? to;

  /// props - 是否在跳转时替换当前页面历史(默认: false)
  final bool replace;

  /// props - 是否开启点击反馈
  final bool? clickable;

  /// props - 是否展示右侧箭头并开启点击反馈(默认: false)
  final bool isLink;

  /// props - 是否显示表单必填星号(默认: false)
  final bool required;

  /// props - 是否使内容垂直居中(默认: false)
  final bool center;

  /// props - 箭头方向，可选值为 left up down (默认: right)
  final VanCellArrowDirection arrowDirection;

  final VanCellStyle? style;

  /// events - 点击事件
  final void Function()? onClick;

  /// props - 左侧标题<br>
  /// slots - 自定义左侧标题<br>
  /// types - [Widget] or [IconData] or [String]
  final dynamic title;

  /// props - 右侧内容<br>
  /// slots - 自定义右侧内容<br>
  /// types - [Widget] or [IconData] or [String]
  final dynamic value;

  /// props - 标题下方的描述信息<br>
  /// slots - 自定义标题下方的描述信息<br>
  /// types - [Widget] or [IconData] or [String]
  final dynamic label;

  /// props - 左侧图标名称或图片链接，等同于 Icon 组件的 name 属性<br>
  /// slots - 自定义左侧图标<br>
  /// types - [Widget] or [IconData] or [String]
  final dynamic icon;

  /// slots - 自定义右侧图标<br>
  /// types - [Widget] or [IconData] or [String]
  final dynamic rightIcon;

  /// slots - 自定义单元格最右侧的额外内容<br>
  /// types - [Widget] or [IconData] or [String]
  final dynamic extra;

  const VanCell({
    super.key,
    this.size = VanCellSize.normal,
    this.layout = VanCellLayout.horizontal,
    this.to,
    this.border,
    this.replace = false,
    this.clickable,
    this.isLink = false,
    this.required = false,
    this.center = false,
    this.arrowDirection = VanCellArrowDirection.right,
    this.style,
    this.onClick,
    this.title,
    this.value,
    this.label,
    this.icon,
    this.rightIcon,
    this.extra,
  });

  VanCellStyle getComputedStyle(BuildContext context) {
    if (style?.isNonNull == true) return style!;
    double? fontSize = style?.fontSize;
    double? lineHeight = style?.lineHeight;
    EdgeInsets? padding = style?.padding;
    Color? textColor = style?.textColor;
    VanBgColor? background = style?.background;
    Color? borderColor = style?.borderColor;
    Color? activeColor = style?.activeColor;
    Color? requiredColor = style?.requiredColor;
    Color? labelColor = style?.labelColor;
    double? labelWidth = style?.labelWidth;
    TextAlign? labelAlign = style?.labelAlign;
    double? labelFontSize = style?.labelFontSize;
    double? labelLineHeight = style?.labelLineHeight;
    double? labelMarginTop = style?.labelMarginTop;
    Color? valueColor = style?.valueColor;
    double? valueFontSize = style?.valueFontSize;
    double? iconSize = style?.iconSize;
    Color? rightIconColor = style?.rightIconColor;
    double? titleFontSize = style?.titleFontSize;

    if (size == VanCellSize.large) {
      padding ??= EdgeInsets.symmetric(
        vertical: kVanCellLargeVerticalPadding.get(context) ?? kVanCellVerticalPadding.get(context),
        horizontal: kVanCellHorizontalPadding.get(context),
      );
      titleFontSize ??= kVanCellLargeTitleFontSize.get(context);
      labelFontSize ??= kVanCellLargeLabelFontSize.get(context);
      valueFontSize ??= kVanCellLargeValueFontSize.get(context);
    }

    kVanCellHorizontalPadding.get(context);

    fontSize ??= kVanCellFontSize.get(context);
    lineHeight ??= kVanCellLineHeight.get(context);
    padding ??= EdgeInsets.symmetric(
      vertical: kVanCellVerticalPadding.get(context) ?? 0,
      horizontal: kVanCellHorizontalPadding.get(context) ?? 0,
    );
    textColor ??= kVanCellTextColor.get(context);
    background ??= kVanCellBackground.get(context);
    borderColor ??= kVanCellBorderColor.get(context);
    activeColor ??= kVanCellActiveColor.get(context);
    requiredColor ??= kVanCellRequiredColor.get(context);
    labelColor ??= kVanCellLabelColor.get(context);
    labelFontSize ??= kVanCellLabelFontSize.get(context);
    labelLineHeight ??= kVanCellLabelLineHeight.get(context);
    labelMarginTop ??= kVanCellLabelMarginTop.get(context);
    valueColor ??= kVanCellValueColor.get(context);
    valueFontSize ??= kVanCellValueFontSize.get(context);
    iconSize ??= kVanCellIconSize.get(context);
    rightIconColor ??= kVanCellRightIconColor.get(context);

    return VanCellStyle(
      fontSize: fontSize,
      lineHeight: lineHeight,
      padding: padding,
      textColor: textColor,
      background: background,
      borderColor: borderColor,
      activeColor: activeColor,
      requiredColor: requiredColor,
      labelColor: labelColor,
      labelAlign: labelAlign,
      labelWidth: labelWidth,
      labelFontSize: labelFontSize,
      labelLineHeight: labelLineHeight,
      labelMarginTop: labelMarginTop,
      valueColor: valueColor,
      valueFontSize: valueFontSize,
      iconSize: iconSize,
      rightIconColor: rightIconColor,
      titleFontSize: titleFontSize,
      titleAlignment: style?.titleAlignment ?? Alignment.centerLeft,
    );
  }

  @override
  Widget build(BuildContext context) {
    final groupStyle = VanCellGroupStyle.of(context);
    final group = VanProvider.of<VanCellGroup>(context);

    final style = getComputedStyle(context);
    final border = this.border ?? group?.border ?? false;

    Widget? title0;
    Widget? value0;
    Widget? label0;
    Widget? icon0;
    Widget? rightIcon0;
    Widget? extra0;

    if (title is Widget) {
      title0 = title;
    } else if (title is String) {
      if (title?.isNotEmpty == true) title0 = Text(title!);
    } else if (title != null) {
      _logger.e("VanCellGroup.title only type support [String] or [Widget].");
    }

    if (value is Widget) {
      value0 = value;
    } else if (value is String) {
      if (value?.isNotEmpty == true) value0 = Text(value!);
    } else if (value != null) {
      _logger.e("VanCellGroup.value only type support [String] or [Widget].");
    }

    if (label is Widget) {
      label0 = label;
    } else if (label is String) {
      if (label?.isNotEmpty == true) label0 = Text(label!);
    } else if (label != null) {
      _logger.e("VanCellGroup.label only type support [String] or [Widget].");
    }

    if (icon is Widget) {
      icon0 = icon;
    } else if (icon is IconData) {
      icon0 = Icon(icon);
    } else if (icon is String) {
      if (icon?.isNotEmpty == true) icon0 = Text(icon!);
    } else if (icon != null) {
      _logger.e("VanCellGroup.icon only type support [String] or [Widget] or [IconData].");
    }

    if (rightIcon is Widget) {
      rightIcon0 = rightIcon;
    } else if (rightIcon is IconData) {
      rightIcon0 = Icon(rightIcon);
    } else if (rightIcon is String) {
      if (rightIcon?.isNotEmpty == true) rightIcon0 = Text(rightIcon!);
    } else if (rightIcon != null) {
      _logger.e("VanCellGroup.rightIcon only type support [String] or [Widget] or [IconData].");
    }

    if (extra is Widget) {
      extra0 = extra;
    } else if (extra is String) {
      if (extra?.isNotEmpty == true) extra0 = Text(extra!);
    } else if (extra != null) {
      _logger.e("VanCellGroup.extra only type support [String] or [Widget].");
    }

    if (title0 != null) {
      title0 = DefaultTextStyle.merge(
        textAlign: style.labelAlign,
        style: TextStyle(
          fontSize: style.titleFontSize,
          color: style.textColor,
          // height: calcLineHeight(
          //   lineHeight: style.lineHeight,
          //   fontSize: style.titleFontSize ?? style.fontSize,
          // ),
        ),
        child: title0,
      );
    }

    if (value0 != null) {
      final fontSize = style.valueFontSize ?? style.fontSize!;
      value0 = DefaultTextStyle(
        style: TextStyle(
          fontSize: fontSize,
          color: style.valueColor,
        ),
        child: value0,
      );
    }

    if (label0 != null) {
      final fontSize = style.labelFontSize ?? style.fontSize!;
      label0 = DefaultTextStyle(
        textAlign: style.labelAlign,
        style: TextStyle(
          color: style.labelColor,
          fontSize: fontSize,
        ),
        child: label0,
      );
    }

    if (extra0 != null) {
      extra0 = DefaultTextStyle.merge(
        style: TextStyle(
          fontSize: style.labelFontSize,
          color: style.labelColor,
        ),
        child: extra!,
      );
    }

    Widget? left0;
    Widget? right0;

    if (title0 != null) left0 = title0;
    if (label0 != null) {
      left0 = left0 == null
          ? label0
          : Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              children: [left0, SizedBox(height: style.labelMarginTop ?? 0), label0],
            );
    }

    if (value0 != null) right0 = value0;
    if (extra0 != null) {
      right0 = right0 == null
          ? extra0
          : Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              mainAxisAlignment: MainAxisAlignment.start,
              children: [right0, SizedBox(height: style.labelMarginTop ?? 0), extra0],
            );
    }

    List<Widget> leftChildren0 = [];
    if (left0 != null) leftChildren0.add(left0);
    if (icon0 != null) {
      final themeData = Theme.of(context).iconTheme.merge(IconThemeData(size: style.iconSize, color: style.textColor));
      icon0 = IconTheme(data: themeData, child: icon0);
      if (leftChildren0.isNotEmpty) {
        leftChildren0 = [icon0, SizedBox(width: kVanPaddingBase.toDouble(context) ?? 0), ...leftChildren0];
      } else {
        leftChildren0.add(icon0);
      }
    }
    if (leftChildren0.isEmpty) {
      left0 = null;
    } else if (leftChildren0.length == 1) {
      left0 = leftChildren0.first;
    } else {
      left0 = Row(
        mainAxisAlignment: style._titleMainAxisAlignment,
          children: leftChildren0);
    }

    List<Widget> rightChildren0 = [];
    if (right0 != null) rightChildren0.add(right0);
    if (rightIcon0 != null) {
      final themeData = Theme.of(context).iconTheme.merge(IconThemeData(size: style.iconSize, color: style.rightIconColor));
      rightIcon0 = IconTheme(data: themeData, child: rightIcon0);
      if (rightChildren0.isNotEmpty) {
        if (rightChildren0.length == 1) rightChildren0[0] = Expanded(child: rightChildren0[0]);
        rightChildren0.add(SizedBox(width: kVanPaddingBase.toDouble(context) ?? 0));
      }
      rightChildren0.add(rightIcon0);
    }
    if (isLink) {
      final themeData = Theme.of(context).iconTheme.merge(IconThemeData(size: style.iconSize, color: style.rightIconColor));
      rightIcon0 = IconTheme(data: themeData, child: Icon(arrowDirection.iconData));
      if (rightChildren0.isNotEmpty) rightChildren0.add(SizedBox(width: kVanPaddingBase.toDouble(context) ?? 0));
      rightChildren0.add(rightIcon0);
    }

    if (rightChildren0.isEmpty) {
      right0 = null;
    } else if (rightChildren0.length == 1) {
      right0 = rightChildren0.first;
    } else {
      right0 = Row(
        // mainAxisAlignment: MainAxisAlignment.end,
        children: rightChildren0,
      );
    }

    List<Widget> children0 = [];
    if (left0 != null) {
      bool expand = true;

      if ((style.labelWidth ?? 0) > 0) {
        left0 = SizedBox(width: style.labelWidth!, child: left0);
        expand = false;
      } else if (left0 is LayoutBuilder || label is LayoutBuilder || title is LayoutBuilder) {
        expand = false;
      }
      if (expand && layout == VanCellLayout.horizontal) {
        left0 = Expanded(child: left0);
      }
      left0 = Align(alignment: style.titleAlignment!, child: left0);
      children0.add(left0);
    }
    if (right0 != null) {
      bool expand = true;
      right0 = Align(alignment: Alignment.centerRight, child: right0);
      if (right0 is LayoutBuilder) {
        expand = false;
      }
      if (expand && layout == VanCellLayout.horizontal) {
        right0 = Expanded(child: right0);
      }
      children0.add(right0);
    }

    BorderRadius? radius = groupStyle?.radius;
    radius ??= group?.inset != true ? null : kVanCellGroupInsetRadius.get(context);

    Widget child0;
    if (layout == VanCellLayout.horizontal) {
      child0 = Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        crossAxisAlignment: center ? CrossAxisAlignment.center : CrossAxisAlignment.start,
        children: children0,
      );
    } else {
      child0 = Column(
        children: children0,
      );
    }

    BoxDecoration? decoration;
    if (border && group?.children?.last != this) {
      decoration = BoxDecoration(
        border: Border(
          bottom: BorderSide(
            color: style.borderColor ?? Colors.transparent,
            width: 0.5,
          ),
        ),
      );
    }

    child0 = Container(
        padding: style.padding?.copyWith(left: 0, right: 0), margin: style.padding?.copyWith(top: 0, bottom: 0), decoration: decoration, child: child0);

    List<VoidCallback> onClicks0 = [];
    if (onClick != null) onClicks0.add(onClick!);
    if (to?.isNotEmpty == true) {
      onClicks0.add(() {
        if (!replace) {
          Navigator.pushNamed(context, to!);
        } else {
          Navigator.pushReplacementNamed(context, to!);
        }
      });
    }

    VoidCallback? onClick0;
    if (onClicks0.isNotEmpty) {
      onClick0 = onClicks0.length == 1
          ? onClicks0.first
          : () {
              for (var onClick1 in onClicks0) {
                onClick1();
              }
            };
    }

    if (clickable == true || isLink == true) {
      child0 = Material(
        color: Colors.transparent,
        child: InkWell(
          splashColor: style.background?.firstColor?.withOpacity(0.1),
          hoverColor: Colors.transparent,
          onTap: onClick0,
          child: child0,
        ),
      );
    } else if (onClick0 != null) {
      child0 = GestureDetector(onTap: onClick0, child: child0);
    }

    child0 = Container(
      width: double.infinity,
      decoration: BoxDecoration(
        color: style.background?.color,
        gradient: style.background?.gradient,
        borderRadius: radius,
      ),
      child: child0,
    );

    return DefaultTextStyle.merge(
        style: TextStyle(
          fontSize: style.fontSize,
          color: style.textColor,
        ),
        child: child0);
  }
}
